package com.wuzao.IOC;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * IOC容器，功能是自动创建对象和对象实例存储，
 * 可以让我们直接使用实例化的对象
 */
public class ApplicationContext {

    /**
     * 存储单例对象
     */
    private final Map<String,Object> singleObjContext;


    public ApplicationContext(List<ObjectConfig> objectConfigs){
        singleObjContext = new HashMap<>();
        for (ObjectConfig objectConfig : objectConfigs) {
            try {
                String beanName = objectConfig.getBeanName();
                Class<?> className = objectConfig.getCl();
                Map<String, Object> diMap = objectConfig.getDiMap();
                Object obj = className.getConstructor().newInstance();
                Field[] fields = className.getDeclaredFields();
                AccessibleObject.setAccessible(fields, true);
                //遍历注入
                for (Field field : fields) {
                    if (diMap.containsKey(field.getName())) {
                        Class<?> cl = diMap.get(field.getName()).getClass();
                        //如果字段类型是传入参数类型的父类型或者相等类型
                        if(field.getType().isAssignableFrom(cl)){
                             field.set(obj,diMap.get(field.getName()));
                        }else{
                            throw new Exception("类型传输错误！！");
                        }
                    }
                }
                singleObjContext.put(beanName, obj);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 从容器中获取指定名称对象
     * @param beanName 对象名称
     * @return
     */
    public Object getObject(String beanName){
        return singleObjContext.get(beanName);
    }

}
